package com.train;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test {

  public static void main(String[] args) {
    User user1 = new User();
    user1.setId(11);

    printResult(user1);

    user1.setUserName("zhangsan");
    printResult(user1);

    user1.setNickName("西门吹牛");
    printResult(user1);

    user1.setAge(10);
    printResult(user1);

    user1.setEmail("zhagnsan@qq.com,zhangsan@163.com");
    printResult(user1);
  }

  public static void printResult(User user) {
    System.err.println("======================================\n" + getQuerySql(user));
  }

  public static String getQuerySql(User user) {
    StringBuffer sb = new StringBuffer();
    //1.获取到Class对象
    Class cls = user.getClass();
    //2.判断是该类上是否存在@Table的注解
    boolean isExistTableAnnotation = cls.isAnnotationPresent(Table.class);
    if (!isExistTableAnnotation) {
      return null;
    }
    Table table = (Table) cls.getAnnotation(Table.class);
    String tableName = table.value();
    sb.append("select * from ").append(tableName).append(" where 1=1 ");
    //3.遍历字段上面所有的注解
    Field[] fields = cls.getDeclaredFields();
    for (Field field : fields) {
      //4.判断该字段上面是否有@Column的注解
      boolean isExistColumnAnnotation = field.isAnnotationPresent(Column.class);
      if (!isExistColumnAnnotation) {
        continue;
      }
      //5.拿到注解上面的值
      Column column = field.getAnnotation(Column.class);
      String columnValue = column.value();
      //6.通过反射拿到属性的值
      Object fieldValue = getFieldValue(user, cls, field);
      //7.组装sql
      if (fieldValue == null) {
        continue;
      }
      sb.append(getAppendSql(columnValue, fieldValue));
    }
    return sb.append(";").toString();

  }

  public static Object getFieldValue(User user, Class cls, Field field) {
    String fieldName = field.getName();
    String getFieldMethodName =
        "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    Method getFieldMethod = null;
    try {
      getFieldMethod = cls.getMethod(getFieldMethodName);
      Object fieldValue = getFieldMethod.invoke(user);
      return fieldValue;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  private static String getAppendSql(String columnValue, Object fieldValue) {
    StringBuffer sb = new StringBuffer();

    if (fieldValue instanceof String) {
      sb.append("\n").append(" and ").append(columnValue);
      String[] values = fieldValue.toString().split(",");
      if (values.length > 1) {
        sb.append(" in (");
        int len = values.length - 1;
        for (int i = 0; i < len; i++) {
          sb.append("\'").append(values[i]).append("\'").append(",");
        }
        sb.append("\'").append(values[len]).append("\'");
        sb.append(") ");
      } else {
        sb.append(" = ").append("\'").append(fieldValue).append("\' ");
      }
    } else if (fieldValue instanceof Integer && (Integer) fieldValue != 0) {
      sb.append("\n").append(" and ").append(columnValue);
      sb.append(" = ").append(fieldValue);
    }

    return sb.toString();
  }
}
